﻿using System;
using System.Collections.Generic;
using UltimateFracturing;
using UnityEngine;

// Token: 0x0200042A RID: 1066
[ExecuteInEditMode]
[Serializable]
public class FracturedChunk : MonoBehaviour
{
	// Token: 0x06001E0F RID: 7695 RVA: 0x000BE898 File Offset: 0x000BCA98
	private void Awake()
	{
		if (Application.isPlaying)
		{
			this.IsDetachedChunk = false;
			base.transform.localPosition = this.m_v3InitialLocalPosition;
			if (this.m_bInitialLocalRotScaleInitialized)
			{
				base.transform.localRotation = this.m_qInitialLocalRotation;
				base.transform.localScale = this.m_v3InitialLocalScale;
			}
			this.ListAdjacentChunksCopy = new List<FracturedChunk.AdjacencyInfo>(this.ListAdjacentChunks);
			this.m_fInvisibleTimer = 0f;
		}
		this.m_bNonSupportedChunkStored = this.IsNonSupportedChunk;
	}

	// Token: 0x06001E10 RID: 7696 RVA: 0x000BE91C File Offset: 0x000BCB1C
	private void Update()
	{
		if (Application.isPlaying)
		{
			if (!base.GetComponent<Renderer>().isVisible && this.IsDetachedChunk)
			{
				this.m_fInvisibleTimer += Time.deltaTime;
				if (this.FracturedObjectSource != null && this.m_fInvisibleTimer > this.FracturedObjectSource.EventDetachedOffscreenLifeTime)
				{
					UnityEngine.Object.Destroy(base.gameObject);
				}
			}
			else
			{
				this.m_fInvisibleTimer = 0f;
			}
		}
	}

	// Token: 0x06001E11 RID: 7697 RVA: 0x000BE9A4 File Offset: 0x000BCBA4
	private void OnCollisionEnter(Collision collision)
	{
		if (collision.contacts == null)
		{
			return;
		}
		if (collision.contacts.Length == 0)
		{
			return;
		}
		this.HandleCollision(collision.collider, collision.contacts[0].point, collision.relativeVelocity.magnitude);
	}

	// Token: 0x06001E12 RID: 7698 RVA: 0x000BE9F8 File Offset: 0x000BCBF8
	private void OnTriggerEnter(Collider other)
	{
		if (this.FracturedObjectSource == null || other == null)
		{
			return;
		}
		Rigidbody attachedRigidbody = other.attachedRigidbody;
		this.HandleCollision(other, other.transform.position, (!(attachedRigidbody != null)) ? 0f : attachedRigidbody.velocity.magnitude);
	}

	// Token: 0x06001E13 RID: 7699 RVA: 0x000BEA60 File Offset: 0x000BCC60
	private void HandleCollision(Collider other, Vector3 v3CollisionPos, float relativeSpeed)
	{
		if (this.FracturedObjectSource == null || other == null)
		{
			return;
		}
		if (other.gameObject)
		{
			FracturedChunk component = other.gameObject.GetComponent<FracturedChunk>();
			if (component && other.attachedRigidbody != null && other.attachedRigidbody.isKinematic && !this.IsDetachedChunk)
			{
				return;
			}
		}
		float num = float.PositiveInfinity;
		Rigidbody attachedRigidbody = other.attachedRigidbody;
		if (attachedRigidbody != null)
		{
			num = attachedRigidbody.mass;
		}
		if (!this.IsDetachedChunk)
		{
			bool flag = false;
			FracturedChunk component2 = other.gameObject.GetComponent<FracturedChunk>();
			if (component2 != null && component2.IsDetachedChunk && component2.FracturedObjectSource == this.FracturedObjectSource)
			{
				flag = true;
			}
			if (!flag && relativeSpeed > this.FracturedObjectSource.EventDetachMinVelocity && num > this.FracturedObjectSource.EventDetachMinMass && base.GetComponent<Collider>() != null && base.GetComponent<Collider>().attachedRigidbody && this.IsDestructibleChunk())
			{
				FracturedChunk.CollisionInfo collisionInfo = new FracturedChunk.CollisionInfo(this, v3CollisionPos, true);
				this.FracturedObjectSource.NotifyDetachChunkCollision(collisionInfo);
				if (!collisionInfo.bCancelCollisionEvent)
				{
					List<FracturedChunk> list = new List<FracturedChunk>();
					list = this.ComputeRandomConnectionBreaks();
					list.Add(this);
					this.DetachFromObject(true);
					foreach (FracturedChunk fracturedChunk in list)
					{
						collisionInfo.chunk = fracturedChunk;
						collisionInfo.bIsMain = false;
						collisionInfo.bCancelCollisionEvent = false;
						if (fracturedChunk != this)
						{
							this.FracturedObjectSource.NotifyDetachChunkCollision(collisionInfo);
						}
						if (!collisionInfo.bCancelCollisionEvent)
						{
							fracturedChunk.DetachFromObject(true);
							fracturedChunk.GetComponent<Collider>().attachedRigidbody.AddExplosionForce(relativeSpeed * this.FracturedObjectSource.EventDetachExitForce, attachedRigidbody.transform.position, 0f, this.FracturedObjectSource.EventDetachUpwardsModifier);
						}
					}
				}
			}
		}
		else
		{
			Rigidbody attachedRigidbody2 = base.GetComponent<Collider>().attachedRigidbody;
			Vector3 a = (!(attachedRigidbody != null)) ? Vector3.zero : attachedRigidbody.velocity;
			float magnitude = (a - attachedRigidbody2.velocity).magnitude;
			if (magnitude > this.FracturedObjectSource.EventDetachedMinVelocity && num > this.FracturedObjectSource.EventDetachedMinMass)
			{
				this.FracturedObjectSource.NotifyFreeChunkCollision(new FracturedChunk.CollisionInfo(this, v3CollisionPos, true));
			}
		}
	}

	// Token: 0x06001E14 RID: 7700 RVA: 0x000BED2C File Offset: 0x000BCF2C
	public bool IsDestructibleChunk()
	{
		if (this.FracturedObjectSource != null)
		{
			if (this.FracturedObjectSource.SupportChunksAreIndestructible)
			{
				return !this.IsSupportChunk;
			}
			if (!this.FracturedObjectSource.SupportChunksAreIndestructible)
			{
				return true;
			}
		}
		return !this.IsSupportChunk;
	}

	// Token: 0x06001E15 RID: 7701 RVA: 0x000BED80 File Offset: 0x000BCF80
	public void ResetChunk(FracturedObject fracturedObjectSource)
	{
		base.transform.parent = fracturedObjectSource.transform;
		base.GetComponent<Rigidbody>().isKinematic = true;
		base.GetComponent<Collider>().isTrigger = (this.FracturedObjectSource.ChunkColliderType == FracturedObject.ColliderType.Trigger);
		this.IsNonSupportedChunk = this.m_bNonSupportedChunkStored;
		this.FracturedObjectSource = fracturedObjectSource;
		this.IsDetachedChunk = false;
		base.transform.localPosition = this.m_v3InitialLocalPosition;
		if (this.m_bInitialLocalRotScaleInitialized)
		{
			base.transform.localRotation = this.m_qInitialLocalRotation;
			base.transform.localScale = this.m_v3InitialLocalScale;
		}
		this.ListAdjacentChunks = new List<FracturedChunk.AdjacencyInfo>(this.ListAdjacentChunksCopy);
		this.m_fInvisibleTimer = 0f;
	}

	// Token: 0x06001E16 RID: 7702 RVA: 0x000BEE38 File Offset: 0x000BD038
	public void Impact(Vector3 v3Position, float fExplosionForce, float fRadius, bool bAlsoImpactFreeChunks)
	{
		if (base.GetComponent<Rigidbody>() != null && this.IsDestructibleChunk())
		{
			List<FracturedChunk> list = new List<FracturedChunk>();
			if (!this.IsDetachedChunk)
			{
				list = this.ComputeRandomConnectionBreaks();
				list.Add(this);
				this.DetachFromObject(true);
				foreach (FracturedChunk fracturedChunk in list)
				{
					fracturedChunk.DetachFromObject(true);
					fracturedChunk.GetComponent<Rigidbody>().AddExplosionForce(fExplosionForce, v3Position, 0f, 0f);
				}
			}
			List<FracturedChunk> destructibleChunksInRadius = this.FracturedObjectSource.GetDestructibleChunksInRadius(v3Position, fRadius, bAlsoImpactFreeChunks);
			foreach (FracturedChunk fracturedChunk2 in destructibleChunksInRadius)
			{
				fracturedChunk2.DetachFromObject(true);
				fracturedChunk2.GetComponent<Rigidbody>().AddExplosionForce(fExplosionForce, v3Position, 0f, this.FracturedObjectSource.EventDetachUpwardsModifier);
			}
		}
		this.FracturedObjectSource.NotifyImpact(v3Position);
	}

	// Token: 0x06001E17 RID: 7703 RVA: 0x000BEF6C File Offset: 0x000BD16C
	public void OnCreateFromFracturedObject(FracturedObject fracturedComponent, int nSplitSubMeshIndex)
	{
		this.FracturedObjectSource = fracturedComponent;
		this.SplitSubMeshIndex = nSplitSubMeshIndex;
		this.RandomMaterialColor = new Color(UnityEngine.Random.value, UnityEngine.Random.value, UnityEngine.Random.value, 0.7f);
		this.m_v3InitialLocalPosition = base.transform.localPosition;
		this.m_qInitialLocalRotation = base.transform.localRotation;
		this.m_v3InitialLocalScale = base.transform.localScale;
		this.m_bInitialLocalRotScaleInitialized = true;
	}

	// Token: 0x06001E18 RID: 7704 RVA: 0x000BEFE0 File Offset: 0x000BD1E0
	public void UpdatePreviewDecompositionPosition()
	{
		float num = 5f;
		float num2 = 1f;
		if (this.FracturedObjectSource != null)
		{
			num2 = this.m_v3InitialLocalPosition.magnitude / this.FracturedObjectSource.DecomposeRadius;
		}
		Vector3 normalized = this.m_v3InitialLocalPosition.normalized;
		base.transform.localPosition = this.m_v3InitialLocalPosition + normalized * (this.PreviewDecompositionValue * num2 * num);
	}

	// Token: 0x06001E19 RID: 7705 RVA: 0x000BF054 File Offset: 0x000BD254
	public void ConnectTo(FracturedChunk chunk, float fArea)
	{
		if (chunk)
		{
			if (chunk.IsConnectedTo(this))
			{
				return;
			}
			this.ListAdjacentChunks.Add(new FracturedChunk.AdjacencyInfo(chunk, fArea));
			chunk.ListAdjacentChunks.Add(new FracturedChunk.AdjacencyInfo(this, fArea));
		}
	}

	// Token: 0x06001E1A RID: 7706 RVA: 0x000BF094 File Offset: 0x000BD294
	public void DisconnectFrom(FracturedChunk chunk)
	{
		if (chunk && chunk.IsConnectedTo(this))
		{
			for (int i = 0; i < this.ListAdjacentChunks.Count; i++)
			{
				if (this.ListAdjacentChunks[i].chunk == chunk)
				{
					this.ListAdjacentChunks.RemoveAt(i);
					break;
				}
			}
			for (int j = 0; j < chunk.ListAdjacentChunks.Count; j++)
			{
				if (chunk.ListAdjacentChunks[j].chunk == this)
				{
					chunk.ListAdjacentChunks.RemoveAt(j);
					break;
				}
			}
		}
	}

	// Token: 0x06001E1B RID: 7707 RVA: 0x000BF14C File Offset: 0x000BD34C
	public bool IsConnectedTo(FracturedChunk chunk)
	{
		foreach (FracturedChunk.AdjacencyInfo adjacencyInfo in this.ListAdjacentChunks)
		{
			bool result = true;
			if (adjacencyInfo.chunk.FracturedObjectSource)
			{
				result = (adjacencyInfo.fArea > adjacencyInfo.chunk.FracturedObjectSource.ChunkConnectionMinArea);
			}
			if (adjacencyInfo.chunk == chunk)
			{
				return result;
			}
		}
		return false;
	}

	// Token: 0x06001E1C RID: 7708 RVA: 0x000BF1EC File Offset: 0x000BD3EC
	public void DetachFromObject(bool bCheckStructureIntegrity = true)
	{
		if (this.IsDestructibleChunk() && !this.IsDetachedChunk && base.GetComponent<Rigidbody>())
		{
			this.m_bNonSupportedChunkStored = this.IsNonSupportedChunk;
			base.transform.parent = null;
			base.GetComponent<Rigidbody>().isKinematic = false;
			base.GetComponent<Collider>().isTrigger = false;
			this.IsDetachedChunk = true;
			this.IsNonSupportedChunk = true;
			this.RemoveConnectionInfo();
			if (this.FracturedObjectSource)
			{
				this.FracturedObjectSource.NotifyChunkDetach(this);
				if (bCheckStructureIntegrity)
				{
					this.FracturedObjectSource.CheckDetachNonSupportedChunks(false);
				}
			}
			if (!this.DontDeleteAfterBroken && this.FracturedObjectSource != null)
			{
				DieTimer dieTimer = base.gameObject.AddComponent<DieTimer>();
				dieTimer.SecondsToDie = UnityEngine.Random.Range(this.FracturedObjectSource.EventDetachedMinLifeTime, this.FracturedObjectSource.EventDetachedMaxLifeTime);
			}
		}
	}

	// Token: 0x06001E1D RID: 7709 RVA: 0x000BF2DC File Offset: 0x000BD4DC
	private void RemoveConnectionInfo()
	{
		foreach (FracturedChunk.AdjacencyInfo adjacencyInfo in this.ListAdjacentChunks)
		{
			if (adjacencyInfo.chunk)
			{
				foreach (FracturedChunk.AdjacencyInfo adjacencyInfo2 in adjacencyInfo.chunk.ListAdjacentChunks)
				{
					if (adjacencyInfo2.chunk == this)
					{
						adjacencyInfo.chunk.ListAdjacentChunks.Remove(adjacencyInfo2);
						break;
					}
				}
			}
		}
		this.ListAdjacentChunks.Clear();
	}

	// Token: 0x06001E1E RID: 7710 RVA: 0x000BF3C0 File Offset: 0x000BD5C0
	public List<FracturedChunk> ComputeRandomConnectionBreaks()
	{
		List<FracturedChunk> list = new List<FracturedChunk>();
		if (this.FracturedObjectSource == null)
		{
			return list;
		}
		this.FracturedObjectSource.ResetAllChunkVisitedFlags();
		FracturedChunk.ComputeRandomConnectionBreaksRecursive(this, list, 1);
		return list;
	}

	// Token: 0x06001E1F RID: 7711 RVA: 0x000BF3FC File Offset: 0x000BD5FC
	private static void ComputeRandomConnectionBreaksRecursive(FracturedChunk chunk, List<FracturedChunk> listBreaksOut, int nLevel)
	{
		if (chunk.Visited)
		{
			return;
		}
		chunk.Visited = true;
		foreach (FracturedChunk.AdjacencyInfo adjacencyInfo in chunk.ListAdjacentChunks)
		{
			if (adjacencyInfo.chunk && chunk.FracturedObjectSource != null && !adjacencyInfo.chunk.Visited && adjacencyInfo.chunk.IsDestructibleChunk())
			{
				bool flag = adjacencyInfo.fArea > chunk.FracturedObjectSource.ChunkConnectionMinArea;
				if (flag)
				{
					float value = UnityEngine.Random.value;
					if (value > chunk.FracturedObjectSource.ChunkConnectionStrength * (float)nLevel)
					{
						FracturedChunk.ComputeRandomConnectionBreaksRecursive(adjacencyInfo.chunk, listBreaksOut, nLevel + 1);
						listBreaksOut.Add(adjacencyInfo.chunk);
					}
				}
			}
		}
	}

	// Token: 0x06001E20 RID: 7712 RVA: 0x000BF4F4 File Offset: 0x000BD6F4
	public static FracturedChunk ChunkRaycast(Vector3 v3Pos, Vector3 v3Forward, out RaycastHit hitInfo)
	{
		FracturedChunk fracturedChunk = null;
		if (Physics.Raycast(v3Pos, v3Forward, out hitInfo))
		{
			fracturedChunk = hitInfo.collider.GetComponent<FracturedChunk>();
			if (fracturedChunk == null && hitInfo.collider.transform.parent != null)
			{
				fracturedChunk = hitInfo.collider.transform.parent.GetComponent<FracturedChunk>();
			}
		}
		return fracturedChunk;
	}

	// Token: 0x04001E2D RID: 7725
	public FracturedObject FracturedObjectSource;

	// Token: 0x04001E2E RID: 7726
	public int SplitSubMeshIndex = -1;

	// Token: 0x04001E2F RID: 7727
	public bool DontDeleteAfterBroken;

	// Token: 0x04001E30 RID: 7728
	public bool IsSupportChunk;

	// Token: 0x04001E31 RID: 7729
	public bool IsNonSupportedChunk;

	// Token: 0x04001E32 RID: 7730
	public bool IsDetachedChunk;

	// Token: 0x04001E33 RID: 7731
	public float RelativeVolume = 0.01f;

	// Token: 0x04001E34 RID: 7732
	public float Volume;

	// Token: 0x04001E35 RID: 7733
	public bool HasConcaveCollider;

	// Token: 0x04001E36 RID: 7734
	public float PreviewDecompositionValue;

	// Token: 0x04001E37 RID: 7735
	public Color RandomMaterialColor = Color.white;

	// Token: 0x04001E38 RID: 7736
	public bool Visited;

	// Token: 0x04001E39 RID: 7737
	public List<FracturedChunk.AdjacencyInfo> ListAdjacentChunks = new List<FracturedChunk.AdjacencyInfo>();

	// Token: 0x04001E3A RID: 7738
	[SerializeField]
	private Vector3 m_v3InitialLocalPosition;

	// Token: 0x04001E3B RID: 7739
	[SerializeField]
	private Quaternion m_qInitialLocalRotation;

	// Token: 0x04001E3C RID: 7740
	[SerializeField]
	private Vector3 m_v3InitialLocalScale;

	// Token: 0x04001E3D RID: 7741
	[SerializeField]
	private bool m_bInitialLocalRotScaleInitialized;

	// Token: 0x04001E3E RID: 7742
	private List<FracturedChunk.AdjacencyInfo> ListAdjacentChunksCopy;

	// Token: 0x04001E3F RID: 7743
	private float m_fInvisibleTimer;

	// Token: 0x04001E40 RID: 7744
	private bool m_bNonSupportedChunkStored;

	// Token: 0x0200042B RID: 1067
	[Serializable]
	public class AdjacencyInfo
	{
		// Token: 0x06001E21 RID: 7713 RVA: 0x000BF55A File Offset: 0x000BD75A
		public AdjacencyInfo(FracturedChunk chunk, float fArea)
		{
			this.chunk = chunk;
			this.fArea = fArea;
		}

		// Token: 0x04001E41 RID: 7745
		public FracturedChunk chunk;

		// Token: 0x04001E42 RID: 7746
		public float fArea;
	}

	// Token: 0x0200042C RID: 1068
	public class CollisionInfo
	{
		// Token: 0x06001E22 RID: 7714 RVA: 0x000BF570 File Offset: 0x000BD770
		public CollisionInfo(FracturedChunk chunk, Vector3 collisionPoint, bool bIsMain)
		{
			this.chunk = chunk;
			this.collisionPoint = collisionPoint;
			this.bIsMain = bIsMain;
			this.bCancelCollisionEvent = false;
		}

		// Token: 0x04001E43 RID: 7747
		public FracturedChunk chunk;

		// Token: 0x04001E44 RID: 7748
		public Vector3 collisionPoint;

		// Token: 0x04001E45 RID: 7749
		public bool bIsMain;

		// Token: 0x04001E46 RID: 7750
		public bool bCancelCollisionEvent;
	}
}
